#!/usr/bin/env python
#coding=utf-8

#from ftplib import FTP  
import ftplib
import sys  
import os.path  

import components

class FtpClient(ftplib.FTP):  
    ''''' 
    conncet to FTP Server 
    '''  
        
    def ConnectFTP(self,remoteip,remoteport,loginname,loginpassword):  
        ftp=FtpClient()

        try:
            #到Python2.6开始增加超时选项
            if components.python_ver() <= '2.5':
                ftp.connect(remoteip,remoteport)
            else:
                ftp.connect(remoteip,remoteport,600)
        except:
            return (False,'conncet failed')  
        else:  
            try:  
                ftp.login(loginname,loginpassword)  
            except:
                return (False,'login failed')  
            else:
                return (True,ftp)  
      
    def download(self,remoteHost,remotePort,loginname,loginpassword,remotePath,localPath):  
        #connect to the FTP Server and check the return  
        res = self.ConnectFTP(remoteHost,remotePort,loginname,loginpassword)  
        if(res[0]!=True):  
            return res  
          
        #change the remote directory and get the remote file size  
        ftp=res[1]  
        ftp.set_pasv(0)  
        dires = self.splitpath(remotePath)  
        if dires[0]:  
            ftp.cwd(dires[0])  
        remotefile=dires[1]  
        #print dires[0]+' '+ dires[1]
        
        try:
            #获取远程文件大小
            fsize=ftp.size(remotefile)  
            if fsize==0 :  
                return  (False,'File size is 0')
        except ftplib.error_perm,e:
            #文件不存在处理
            errmsg = "%s" % e
            return (False,errmsg)
          
        #check local file isn't exists and get the local file size  
        lsize=0L  
        #if os.path.exists(localPath):  
            #lsize=os.stat(localPath).st_size  
              
        #if lsize >= fsize:  
            #print 'local file is bigger or equal remote file'  
            #return
        
        blocksize=1024  
        cmpsize=lsize  
        ftp.voidcmd('TYPE I')  
        #conn = ftp.transfercmd('RETR '+remotefile,lsize)  
        conn = ftp.transfercmd('RETR '+remotefile)  
        
        lwrite=open(localPath,'ab')
        try:
            while True:  
                data=conn.recv(blocksize)  
                if not data:  
                    break  
                lwrite.write(data)  
                cmpsize+=len(data)  
                #print '\b'*30,'download process:%.2f%%'%(float(cmpsize)/fsize*100),  
                #print 'download process:%.2f%%\n' % (float(cmpsize)/fsize*100),
            lwrite.close()  
            ftp.voidcmd('NOOP')  
            ftp.voidresp()  
            conn.close()  
            ftp.quit()
            
            return (True,'download ok') 
        except ftplib.error_temp,e:
            #下载失败处理
            errmsg = "%s" % e
            return (False,errmsg)
        
    
    def upload(self,remotehost,remoteport,loginname,loginpassword,remotepath,localpath,callback=None):  
        if not os.path.exists(localpath):  
            print "Local file doesn't exists"  
            return  
        self.set_debuglevel(2)  
        res=self.ConnectFTP(remotehost,remoteport,loginname,loginpassword)  
        if res[0]!=True:  
            print res[1]  
            sys.exit()  
        ftp=res[1]  
        remote=self.splitpath(remotepath)  
        ftp.cwd(remote[0])  
        rsize=0L  
        try:  
            rsize=ftp.size(remote[1])  
        except:  
            pass  
        if (rsize==None):  
            rsize=0L  
        lsize=os.stat(localpath).st_size  
        if (rsize==lsize):  
            print 'remote filesize is equal with local'  
            return  
        if (rsize<lsize):  
            localf=open(localpath,'rb')  
            localf.seek(rsize)  
            ftp.voidcmd('TYPE I')  
            #datasock,esize=ftp.ntransfercmd("STOR "+remote[1],rsize)  
            datasock,esize=ftp.ntransfercmd("STOR "+remote[1])  
            cmpsize=rsize  
            while True:  
                buf=localf.read(1024)  
                if not len(buf):  
                    print '\rno data break'  
                    break  
                datasock.sendall(buf)  
                if callback:  
                    callback(buf)  
                cmpsize+=len(buf)  
                #print '\b'*30,'uploading %.2f%%'%(float(cmpsize)/lsize*100),
                print 'uploading %.2f%%\n' % (float(cmpsize)/lsize*100),  
                if cmpsize==lsize:  
                    print '\rfile size equal break'  
                    break  
            datasock.close()   
            localf.close()   
            ftp.voidcmd('NOOP')  
            ftp.voidresp()
            ftp.quit()  
              
          
    def splitpath(self,remotepath):  
        position=remotepath.rfind('/')  
        return (remotepath[:position+1],remotepath[position+1:])  
        
          
#if __name__=='__main__':  
    #lf = FtpClient()
    ##lf.ConnectFTP("192.168.100.237","21","cooler","123123")
    #print lf.download("172.17.0.19","21","sftang","123456","/8af9ab34ecdf11e1a040000c29c90e28.rar","d:/8af9ab34ecdf11e1a040000c29c90e28.rar")
    ##lf.upload("172.17.0.19","21","sftang","123456","/21.rar","d:/8af9ab34ecdf11e1a040000c29c90e28.rar")
